package com.yonyou.pmclouds.workconnect.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.billview.entity.BillViewQueryVO;
import com.yonyou.pmclouds.contacttype.entity.ContactTypeVO;
import com.yonyou.pmclouds.contacttype.service.rmiitf.ContactTypeRemoteMobService;
import com.yonyou.pmclouds.contacttype.service.rmiitf.ContactTypeRemoteService;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.pmpub.entity.QueryListParam;
import com.yonyou.pmclouds.pmpub.rmiitf.IPageQuerySerivce;
import com.yonyou.pmclouds.procedure.entity.ProcedureRefVO;
import com.yonyou.pmclouds.procedure.entity.ProcedureVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.projectpart.service.IProjectpartQryService;
import com.yonyou.pmclouds.workConnect.entity.WorkConBillStatus;
import com.yonyou.pmclouds.workConnect.entity.WorkConReceiverVO;
import com.yonyou.pmclouds.workConnect.entity.WorkConnectVO;
import com.yonyou.pmclouds.workConnect.service.rmiitf.WorkConReceiverQuery;
import com.yonyou.pmclouds.workConnect.service.rmiitf.WorkConnectQuery;
import com.yonyou.pmclouds.workconnect.mapper.WorkConnectMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 工作联系查询接口
 */
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = WorkConnectQuery.class)
public class WorkConnectQueryImpl implements WorkConnectQuery, IPageQuerySerivce<WorkConnectVO> {

    @Autowired
    private WorkConnectMapper workConnectMapper;

    @Autowired
    private WorkConReceiverQuery receiverQuery;

    @Autowired
    private ProjectSimpleQuery projectQuery;

    @Autowired
    private ProcedureQuery processQuery;

    @Autowired
    private ContactTypeRemoteMobService contypeMobQuery;

    @Autowired
    private ContactTypeRemoteService contypeQuery;

    @Autowired
    private PictureRemoteService picService;

    @Autowired
    private WorkConReceiverQuery workConReceiverQuery;

    @Autowired
    private OrganizationQuery organizationQuery;

    @Autowired
    private IProjectpartQryService projectpartQryService;

    /**
     * 根据项目查询工作联系
     * @param pk_project
     * @return
     * @throws BusinessException
     */
    @Override
    public List<WorkConnectVO> selectByPkProject(String pk_project) throws BusinessException {
        List<WorkConnectVO> list = workConnectMapper.selectByPkProject(pk_project);
        getPictures(list); //添加照片
        //填充工程部位名称
        if(CollectionUtils.isNotEmpty(list)){
            projectpartQryService.fillProjectpartName(list.toArray(new WorkConnectVO[]{}));
        }
        return list;
    }


    /**
     * 封装图片信息
     * @param vos
     * @throws BusinessException
     */
    private void getPictures(List<WorkConnectVO> vos) throws BusinessException {
        if (CollectionUtils.isEmpty(vos)){
            return;
        }
        //获取主键
//        List<String> pkBills = vos.stream().filter(vo -> vo != null && vo.getPk_workconnect() != null).map(WorkConnectVO::getPk_workconnect).collect(Collectors.toList());
        List<String> pkBills = vos.stream().map(WorkConnectVO::getPk_workconnect).collect(Collectors.toList());
        if (pkBills.size() == 0) {
            return ;
        }
        Map<String, List<String>> picMap = picService.queryPicsByPkEntitys(pkBills.toArray(new String[0]));
        if (picMap == null) return;

        for (WorkConnectVO vo : vos) {
            if (vo != null && picMap.get(vo.getPk_workconnect()) != null) {
                vo.setPictures(picMap.get(vo.getPk_workconnect()).toArray(new String[0]));
            }
        }
    }

    /**
     * 查询工作联系详情
     * @param pk_workconnect
     * @return
     * @throws BusinessException
     */
    @Override
    public WorkConnectVO selectOne(String pk_workconnect) throws BusinessException {
        //查询工作联系
        WorkConnectVO workConnectVO = workConnectMapper.getById(pk_workconnect);
        if (workConnectVO == null) {
            throw new BusinessException("该工作联系单不存在!");
        }
        //设置接收人信息
        if (StringUtils.isEmpty(workConnectVO.getPkReceiver())) {
            workConnectVO = setReceivers(workConnectVO);
        }
        //设置图片信息
        workConnectVO = setPics(workConnectVO);

        return setRefFiledInfo(workConnectVO);
    }

    /**
     * 为workconnect设置workConReceiverVOS属性
     *
     * @param workConnectVO
     * @return
     */
    private WorkConnectVO setReceivers(WorkConnectVO workConnectVO) throws BusinessException {
        WorkConReceiverVO[] receiverVOS = receiverQuery.queryByWorkConnect(workConnectVO.getPk_workconnect());
        workConnectVO.setWorkConReceiverVOS(receiverVOS);
        return workConnectVO;
    }

    @Override
    public String[] queryPics(String pk_workconnect) throws BusinessException {
        return picService.queryPicNamesByPkEntity(pk_workconnect);
    }

    @Override
    public boolean queryRefByIds(String code, String[] ids) throws BusinessException {
        boolean flag = false;
        Integer count = workConnectMapper.selectRefByCode(code, ids);
        if (count != null && count > 0) {
            flag = true;
        }
        return flag;
    }

    @Override
    public PageObject<Object> queryByCondition(BillViewQueryVO billViewQueryVO) throws BusinessException {
        String[] pkProjects = billViewQueryVO.getPkProject();
        String[] creators = billViewQueryVO.getCreators();
        String startDate = billViewQueryVO.getStartTime();
        String endDate = billViewQueryVO.getEndTime();
        int[] billStatus = billViewQueryVO.getBillStatus();
        int pageStart = billViewQueryVO.getPageStart();
        int pageSize = billViewQueryVO.getPageSize();
        JSONObject extendsParams = billViewQueryVO.getExtendsParams();
        String[] pkContactTypes = extendsParams != null && StringUtils.isNotBlank(extendsParams.getString("pk_contactTypes")) ? extendsParams.getString("pk_contactTypes").split(",") : null;
        String[] pkorgs = extendsParams != null && StringUtils.isNotBlank(extendsParams.getString("pkorgs")) ? extendsParams.getString("pkorgs").split(",") : null;
        int count = workConnectMapper.countByCondition(pkProjects, creators, startDate, endDate, pkorgs, pkContactTypes, RuntimeEnvironment.getTenantId(), billStatus);

        WorkConnectVO[] workConnectVOs = workConnectMapper.queryByCondition(pkProjects, creators, startDate, endDate, billStatus, pkorgs, pkContactTypes, RuntimeEnvironment.getTenantId(), pageStart, pageSize);

        return new PageObject<Object>(setRefFiledInfo(workConnectVOs), count, pageStart);
    }

    /**
     *
     * @param vo
     * @return
     * @throws BusinessException
     */
    private WorkConnectVO setRefFiledInfo(WorkConnectVO vo) throws BusinessException {
        // 联系类型
        ContactTypeVO typeVO = contypeMobQuery.queryById(vo.getPk_contacttype());
        vo.setContype_name(typeVO.getContype_name());
        // 工序
        String pk_process = vo.getPk_process();
        if (!StringUtils.isEmpty(pk_process)) {
            ProcedureVO procedureVO = processQuery.getById(pk_process);
            vo.setProcess_name(procedureVO.getSname());
        }
        // 项目
        ProjectVO projectVO = projectQuery.queryProject(vo.getPk_project());
        vo.setProject_name(projectVO.getSname());
        vo.setProject_code(projectVO.getScode());

        String pkOrg = projectVO.getPkOrg();
        if (StringUtils.isNotEmpty(pkOrg)) {
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), pkOrg);
            vo.setOrgName(organizationVO == null ? null : organizationVO.getSname());
        }
        if(WorkConBillStatus.STATUS_ACCEPTED == vo.getBillstatus()){
            vo.setStrBillstatus(WorkConReceiverVO.RECEIVE_STATUS_ACCEPTED_NAME);
        }else{
            vo.setStrBillstatus(WorkConReceiverVO.RECEIVE_STATUS_UNACCEPT_NAME);
        }
        //填充工程部位名称
        projectpartQryService.fillProjectpartName(vo);
        return vo;
    }

    private WorkConnectVO setPics(WorkConnectVO vo) throws BusinessException {
        vo.setPictures(queryPics(vo.getPk_workconnect()));
        return vo;
    }

    /**
     * 处理参照字段，非必输项需校验空
     *
     * @param vos
     * @return
     * @throws BusinessException
     */
    private WorkConnectVO[] setRefFiledInfo(WorkConnectVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return new WorkConnectVO[0];
        }
        //工序
        List<String> procSet = Arrays.stream(vos).map(WorkConnectVO::getPk_process).collect(Collectors.toList());
        //项目
        List<String> projectSet = Arrays.stream(vos).map(WorkConnectVO::getPk_project).collect(Collectors.toList());
        //主键
        List<String> pkSet = Arrays.stream(vos).map(WorkConnectVO::getPk_workconnect).collect(Collectors.toList());
        //联系类型
        List<String> pkConType = Arrays.stream(vos).map(WorkConnectVO::getPk_contacttype).collect(Collectors.toList());


        //批量获取信息
        Map<String, ProcedureRefVO> procedureRefVOMap = processQuery.queryRefs(procSet.toArray(new String[0]));
        Map<String, ProjectVO> projectVOMap = projectQuery.queryProjects(projectSet.toArray(new String[0]));
        List<ContactTypeVO> contactTypeVOList = contypeQuery.queryConTypesByPK(pkConType.toArray(new String[0]));
        Map<String, OrganizationVO> stringOrganizationVOMap = obtailPkorgByProject(projectVOMap);
        Map<String, List<String>> picMap = picService.queryPicsByPkEntitys(pkSet.toArray(new String[0]));

        Map<String, ContactTypeVO> contactTypeVOMap = contactTypeVOList.stream().collect(Collectors.toMap(ContactTypeVO::getPk_contacttype, v -> v));

        wrapWorkConnectInfo(vos, pkSet, procedureRefVOMap, projectVOMap, stringOrganizationVOMap, picMap, contactTypeVOMap);

        //填充工程部位名称
        projectpartQryService.fillProjectpartName(vos);

        return vos;
    }

    /**
     * 封装联系类型信息
     * @param vos
     * @param pkSet
     * @param procedureRefVOMap
     * @param projectVOMap
     * @param stringOrganizationVOMap
     * @param picMap
     * @param contactTypeVOMap
     * @throws BusinessException
     */
    private void wrapWorkConnectInfo(WorkConnectVO[] vos, List<String> pkSet, Map<String, ProcedureRefVO> procedureRefVOMap, Map<String, ProjectVO> projectVOMap, Map<String, OrganizationVO> stringOrganizationVOMap, Map<String, List<String>> picMap, Map<String, ContactTypeVO> contactTypeVOMap) throws BusinessException {
        WorkConReceiverVO[] workConReceiverVOS = workConReceiverQuery.queryByWorkConnects(pkSet.toArray(new String[0]));
        Map<String, List<WorkConReceiverVO>> collect = null;
        if(workConReceiverVOS != null && workConReceiverVOS.length > 0) {
            collect = Arrays.stream(workConReceiverVOS).collect(Collectors.groupingBy(WorkConReceiverVO::getPkWorkconnect));
        }
        for (WorkConnectVO vo :  vos) {
            List<WorkConReceiverVO> workConReceivers = collect.get(vo.getPk_workconnect());
            if(CollectionUtils.isEmpty(workConReceivers)){
                //处理工作联系的旧数据
                vo.setPkReceivers(new String[]{vo.getPkReceiver()});
            }
            vo.setProcess_name(procedureRefVOMap.get(vo.getPk_process()) == null ? null : procedureRefVOMap.get(vo.getPk_process()).getSname());
            vo.setProject_name(projectVOMap.get(vo.getPk_project()) == null ? null : projectVOMap.get(vo.getPk_project()).getSname());
            vo.setProject_code(projectVOMap.get(vo.getPk_project()) == null ? null : projectVOMap.get(vo.getPk_project()).getScode());
            vo.setContype_name(contactTypeVOMap.get(vo.getPk_contacttype()) == null ? null : contactTypeVOMap.get(vo.getPk_contacttype()).getContype_name());
//            vo.setPkReceivers(receiverMap.get(vo.getPk_workconnect()) == null ? new String[0] : receiverMap.get(vo.getPk_workconnect()).toArray(new String[0]));
            vo.setPicNum(picMap.get(vo.getPk_workconnect()) == null ? 0 : picMap.get(vo.getPk_workconnect()).size());
            if (projectVOMap.get(vo.getPk_project()) != null && StringUtils.isNotBlank(projectVOMap.get(vo.getPk_project()).getPkOrg())) {
                OrganizationVO organizationVO = stringOrganizationVOMap.get(projectVOMap.get(vo.getPk_project()).getPkOrg());
                vo.setOrgName(organizationVO != null && StringUtils.isNotBlank(organizationVO.getSname()) ? organizationVO.getSname() : "");
            }
            if(collect != null &&collect.size() > 0){
                vo.setWorkConReceiverVOS(workConReceivers.toArray(new WorkConReceiverVO[0]));
            }
        }
    }

    /**
     * 获取项目组织
     * @param projectMap
     * @return
     * @throws BusinessException
     */
    private Map<String, OrganizationVO> obtailPkorgByProject(Map<String, ProjectVO> projectMap) throws BusinessException {
        Map<String, OrganizationVO> proToOrgMap = new HashMap<String, OrganizationVO>();
        if (projectMap != null && projectMap.size() > 0) {
            List<String> pkOrgs = projectMap.values().stream().map(ProjectVO::getPkOrg).filter(vo -> StringUtils.isNotEmpty(vo)).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(pkOrgs)) {
                OrganizationVO[] organizationVOs = organizationQuery.queryByPkSrcs(RuntimeEnvironment.getTenantId(), pkOrgs.toArray(new String[0]));
                proToOrgMap = Arrays.stream(organizationVOs).filter(organizationVO -> StringUtils.isNotEmpty(organizationVO.getPkSrc()))
                        .collect(Collectors.toMap(OrganizationVO::getPkSrc, organizationVO -> organizationVO));
            }
        }
        return proToOrgMap;
    }

    /**
     * 根据项目查新工作联系的数量
     * @param param
     * @return
     * @throws BusinessException
     */
    @Override
    public int countByProject(QueryListParam param) throws BusinessException {

        int count = workConnectMapper.countByCondition(new String[]{param.getPkProject()}, null, param.getStartDate(), param.getEndDate(), null, null, null, null);

        return count;
    }

    /**
     * 根据项目查询工作联系
     * @param param
     * @return
     * @throws BusinessException
     */
    @Override
    public WorkConnectVO[] queryByProject(QueryListParam param) throws BusinessException {
        WorkConnectVO[] vos = workConnectMapper.queryByCondition(new String[]{param.getPkProject()}, null, param.getStartDate(), param.getEndDate(), null, null, null, null, param.getPageStart(), param.getPageSize());
        getPictures(Arrays.asList(vos));
        //填充工程部位名称
        projectpartQryService.fillProjectpartName(vos);
        return vos;
    }

    @Override
    public String getBillType() {
        return BillTypeConst.WORKCONNECT_BILLTYPE;
    }
}
